﻿using System;
using System.Collections.Generic;
using System.Reflection;

using TypeConverter = System.ComponentModel.TypeConverter;

namespace Sencha.Serialization.Contracts
{
	public sealed class MemberDescription : IComparable, IComparable<MemberDescription>
	{
		private readonly MemberInfo m_member;
		// Properties
		public IList<Attribute> Attributes { get; internal set; }

		public TypeDescription DeclaringType { get; private set; }
		public string Name { get; internal set; }
		internal string NameAsJson { get; set; }
		public string FieldName { get; internal set; }
		//public Type MemberType { get; internal set; }
		//public TypeInfo MemberTypeInfo { get; internal set; }
		//public IList<TypeInfo> AlternativeMemberTypes { get; internal set; }
		//public Type ConverterType { get; internal set; }
		public int Ordinal { get; internal set; }
		//public bool IsReadOnly { get; internal set; }

		//public bool CanResetValue(object component) { return m_invoker.CanResetValue(m_member, component); }
		//public void ResetValue(object component) { m_invoker.ResetValue(m_member, component); }
		//public object GetValue(object component) { return m_invoker.GetValue(m_member, component); }
		//public void SetValue(object component, object value) { m_invoker.SetValue(m_member, component, value); }

		internal MemberDescription(TypeDescription declaringType, MemberInfo metadataMember)
		{
			if (metadataMember == null)
				throw new ArgumentNullException("memberInstance");
			System.Diagnostics.Contracts.Contract.EndContractBlock();

			m_member = metadataMember;
			this.DeclaringType = declaringType;
		}

		#region IComparable Members

		public int CompareTo(object obj)
		{
			return this.CompareTo(obj as MemberDescription);
		}

		#endregion
		#region IComparable<MemberInfo> Members

		public int CompareTo(MemberDescription other)
		{
			if (other == null)
				return 1;

			return this.Name.CompareTo(other.Name);
		}

		#endregion
		public override int GetHashCode()
		{
			return (this.Name ?? string.Empty).GetHashCode();
		}
		public override bool Equals(object obj)
		{
			if (this == obj)
				return true;
			if (obj == null)
				return false;
			if (obj is MemberDescription)
			{
				var other = (obj as MemberDescription);

				return this.m_member.Equals(other.m_member);
			}
			else
				return false;
		}

		public override string ToString()
		{
			//return string.Format("{0} {1}", Name, MemberType);
			return this.Name;
		}
	}
}
